home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 5
/
Aminet 5 - March 1995.iso
/
Aminet
/
util
/
cli
/
MCommands_1_2.lha
/
Src
/
for.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-02
|
6KB
|
248 lines
#define __USE_SYSBASE
#include <exec/types.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <dos/rdargs.h>
#include <dos/dosasl.h>
#include <dos/dosextens.h>
#include <dos/dostags.h>
#include <utility/tagitem.h>
#include <support/types.h>
#include <support/exec.h>
#include <support/dos.h>
#include <string.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include "for.rev.h"
#define DOS_NAME "dos.library"
#define DOS_VERN 37L
#define TEMPLATE "FILE/M,DO/K/F,ALL/S,NOQUOTE=NQ/S"
#define DEF_COMM "%S"
STATIC CONST TEXT VersionString[]=
VERSION(PROG_NAME,PROG_VERSION,PROG_REVISION,PROG_DATE);
#define OPT_FILE 0
#define OPT_DO 1
#define OPT_ALL 2
#define OPT_NQ 3
#define OPT_COUNT 4
#define NAME_SIZE 32 /* File's name */
#define COMM_SIZE 1024 /* Unexpanded command */
#define PRSD_SIZE 1024 /* Expanded command */
#define PATH_SIZE 256 /* For file's path */
#define CommString (Opts[OPT_DO] ? (STRPTR)Opts[OPT_DO] : RawComm)
STATIC BOOL PrepComm(STRPTR format, STRPTR buffer, ULONG buffSize,
STRPTR name, STRPTR path, BOOL quote);
STATIC BOOL CopyComm(STRPTR *args, STRPTR buffer, ULONG buffSize);
ULONG For(VOID)
{
struct ExecBase *SysBase=*((struct ExecBase **)4);
struct DosLibrary *DOSBase;
STATIC CONST struct TagItem CommandTags[]=
{
{SYS_UserShell,TRUE},
{TAG_DONE,0}
};
STATIC CONST STRPTR DefFile[]={"#?",NULL};
struct RDArgs *Args;
struct AnchorPath *Anchor;
LONG Opts[OPT_COUNT];
ULONG I,TempRC,RC=RETURN_FAIL;
CHAR FName[NAME_SIZE];
STRPTR RawComm,ParsedComm,CurArg,*ArgPtr;
BPTR CurrLock,OldLock;
BOOL ErrOccured=FALSE,MultiFile=TRUE;
unless(DOSBase=(struct DosLibrary *)OpenLibrary(DOS_NAME,DOS_VERN))
{
SetResult2(ERROR_INVALID_RESIDENT_LIBRARY);
goto InvalidDOS;
}
unless(Anchor=AllocVec(sizeof(struct AnchorPath)+PATH_SIZE,MEMF_CLEAR))
{
PrintFault(IoErr(),NULL); /* Inform user */
goto NoMemory1;
}
Anchor->ap_BreakBits=SIGBREAKF_CTRL_C; /* Allow break */
Anchor->ap_Strlen=PATH_SIZE;
unless(RawComm=AllocVec(COMM_SIZE+PRSD_SIZE,MEMF_CLEAR))
{
PrintFault(IoErr(),NULL); /* Inform user */
goto NoMemory2;
}
ParsedComm=RawComm+COMM_SIZE;
clear(&Opts);
unless(Args=ReadArgs(TEMPLATE,Opts,NULL))
{
PrintFault(IoErr(),NULL); /* Inform user */
goto NoArgs;
}
ArgPtr=Opts[OPT_FILE] ? (STRPTR *)Opts[OPT_FILE] : DefFile;
unless(Opts[OPT_DO]) /* 'DO' not specified, */
{ /* This is <file>+<command> */
if(ArgPtr[1]) /* Only one file patern specified */
{
unless(CopyComm(ArgPtr,RawComm,COMM_SIZE)) /* Copy patterns to command */
{
CauseIoErr(ERROR_LINE_TOO_LONG,NULL);
goto Exit;
}
MultiFile=FALSE; /* There is only one file */
}
else /* Multiple patterns */
stpcpy(RawComm,DEF_COMM); /* Set command to "run" */
}
for(I=0; (CurArg=*ArgPtr++) && (I==0 || MultiFile); I++)
{
clear(Anchor);
Anchor->ap_BreakBits=SIGBREAKF_CTRL_C; /* Allow break */
Anchor->ap_Strlen=PATH_SIZE; /* We have a path buffer */
TempRC=MatchFirst(CurArg,Anchor);
while(TempRC==0)
{
stpcpy(FName,Anchor->ap_Info.fib_FileName);
if(Anchor->ap_Info.fib_DirEntryType>=0)
{
if(Opts[OPT_ALL])
{
if(!ftst(Anchor->ap_Flags,APF_DIDDIR))
fset(Anchor->ap_Flags,APF_DODIR);
fclr(Anchor->ap_Flags,APF_DIDDIR);
}
goto Next;
}
CurrLock=DupLock(Anchor->ap_Current->an_Lock);
OldLock=CurrentDir(CurrLock);
if(PrepComm(CommString,ParsedComm,PRSD_SIZE,
FName,Anchor->ap_Buf,!Opts[OPT_NQ]))
{
if(System(ParsedComm,CommandTags)) /* An error */
{
ErrOccured=TRUE;
PrintFault(IoErr(),FName);
}
}
else
{
ErrOccured=TRUE;
CauseIoErr(ERROR_LINE_TOO_LONG,NULL);
}
CurrentDir(OldLock);
UnLock(CurrLock);
Next:
TempRC=MatchNext(Anchor);
}
if(TempRC==ERROR_NO_MORE_ENTRIES)
RC=(ErrOccured ? RETURN_ERROR : RETURN_OK);
else
{
PrintFault(TempRC,NULL);
RC=(TempRC==ERROR_BREAK ? RETURN_WARN : RETURN_FAIL);
}
MatchEnd(Anchor);
if(TempRC==ERROR_BREAK)
break;
}
Exit:
FreeArgs(Args);
NoArgs:
FreeVec(RawComm);
NoMemory2:
FreeVec(Anchor);
NoMemory1:
CloseLibrary((struct Library *)DOSBase);
InvalidDOS:
return(RC);
}
STATIC BOOL PrepComm(STRPTR format, STRPTR buffer, ULONG buffSize,
STRPTR name, STRPTR path, BOOL quote)
{
ULONG NameLen=strlen(name),PathLen=strlen(path),Len;
CHAR CurrChar;
STRPTR Arg,HighBuffer=buffer+buffSize-1;
memset(buffer,0,buffSize); /* Clear buffer */
while(CurrChar=*format++)
{
if(buffer<HighBuffer) /* The char will fit */
*buffer=CurrChar;
else
return(FALSE);
if(CurrChar=='%')
{
switch(*format)
{
case 's':
case 'S':
Len=NameLen;
Arg=name;
break;
case 'p':
case 'P':
Len=PathLen;
Arg=path;
break;
case '%':
format++;
default:
buffer++;
continue;
}
if(buffer+Len+(quote ? 2 : 0)<HighBuffer)
{
if(quote)
*buffer++='"';
buffer=stpcpy(buffer,Arg); /* Insert arg */
if(quote)
*buffer++='"';
format++; /* Skip control char */
}
else
return(FALSE);
}
else
buffer++;
}
return(TRUE);
}
STATIC BOOL CopyComm(STRPTR *args, STRPTR buffer, ULONG buffSize)
{
ULONG I;
STRPTR Arg,HighBuffer=buffer+buffSize-1;
memset(buffer,0,buffSize); /* Clear buffer */
for(I=1; Arg=args[I]; I++) /* While there is an arg to add */
if(buffer+strlen(Arg)+1<HighBuffer) /* This arg will fit */
{
if(I>1) /* Not first arg */
*buffer++=' '; /* Add one separating space */
buffer=stpcpy(buffer,Arg); /* Copy this arg */
}
else
return(FALSE);
return(TRUE);
}